import os

from lucommon.logger import lu_logger

import agent
import conf
from async_task.services import register_job, AsyncTask
from deploy.services import nginx as NGINX
from utils import gen_static_dir, get_static_url, concurrence_requests, clean_path
from . import check_agent_status, check_concurrence_result


class AsyncTaskDeployNginx(AsyncTask):
    def task_impl(self, nodes, pkg, application_dir, nginx_service_path, nginx_conf_path, empty_conf_path):
        request_infos = {}
        for ip in nodes:
            request_infos[str(ip)] = {
                "url": "http://{}:{}{}".format(ip, agent.AGENT_PORT, agent.INSTALL_NGINX),
                "method": "POST",
                "timeout": 900,
                "json": {
                    "pkg_url": {"url": pkg.url, "extract_type": pkg.extract_type, "save_path": ""},
                    "application_dir": application_dir,
                    "depend_pkg": {
                        "pcre": {
                            "url": conf.PCRE_PACKAGE["8.45"].url,
                            "extract_type": conf.PCRE_PACKAGE["8.45"].extract_type,
                            "save_path": "",
                        },
                        "zlib": {
                            "url": conf.ZLIB_PACKAGE["1.3"].url,
                            "extract_type": conf.ZLIB_PACKAGE["1.3"].extract_type,
                            "save_path": "",
                        },
                        "openssl": {
                            "url": conf.OPENSSL_PACKAGE["1.1"].url,
                            "extract_type": conf.OPENSSL_PACKAGE["1.1"].extract_type,
                            "save_path": "",
                        },
                    },
                    "depend_files": [
                        {
                            "url": get_static_url(nginx_service_path),
                            "save_path": clean_path("{}/{}".format(conf.SERVICE_DIR, NGINX.NGINX_SERVER_NAME))
                        },  # service file
                        {
                            "url": get_static_url(nginx_conf_path),
                            "save_path": os.path.join(application_dir, "nginx", "conf", "nginx.conf"),
                        },  # default conf file
                        {
                            "url": get_static_url(empty_conf_path),
                            "save_path": os.path.join(application_dir, "nginx", "conf", NGINX.NGINX_HTTP_CONFIG_DIR,
                                                      NGINX.HTTP_EMPTY_CONF),
                        },  # default http conf file
                        {
                            "url": get_static_url(empty_conf_path),
                            "save_path": os.path.join(application_dir, "nginx", "conf", NGINX.NGINX_STREAM_CONFIG_DIR,
                                                      NGINX.STREAM_EMPTY_CONF),
                        },  # default stream conf file
                    ],
                    "external_pkg": {
                        "nginx-module-vts": {
                            "url": conf.NGINX_MODULE_VTS_PACKAGE["0.2.2"].url,
                            "extract_type": conf.NGINX_MODULE_VTS_PACKAGE["0.2.2"].extract_type,
                            "save_path": "",
                        },
                    },
                }
            }
        lu_logger.debug("request_infos:{}".format(request_infos))
        nginx_result = concurrence_requests(request_infos)
        if check_concurrence_result(nginx_result):
            return 0, nginx_result
        return -1, nginx_result


class AsyncTaskDeployK8SLBWithNginx(AsyncTask):

    def task_impl(self, nodes, nginx_config_dir, nginx_conf_path, conf_name):
        request_infos = {}
        for ip in nodes:
            request_infos[str(ip)] = {
                "url": "http://{}:{}{}".format(ip, agent.AGENT_PORT, agent.INSTALL_LB_WITH_NGINX),
                "method": "POST",
                "json": {
                    "nginx_conf_dir": nginx_config_dir,
                    "depend_files": [
                        {
                            "url": get_static_url(nginx_conf_path),
                            "extract_type": "",
                            "save_path": os.path.join(nginx_config_dir, conf_name)
                        },
                    ],
                }
            }
        lu_logger.debug("request_infos:{}".format(request_infos))
        lb_result = concurrence_requests(request_infos)
        if check_concurrence_result(lb_result):
            return 0, lb_result
        return -1, lb_result


def job_deploy_nginx(params):
    application_dir = params["application_dir"]
    nodes = params["nodes"]
    nodes = list(set(nodes))
    version = params["version"]

    pkg = conf.NGINX_PACKAGE.get(str(version))
    if not pkg:
        return -1, "无适用的nginx package,valid_version:{}".format(",".join(list(conf.NGINX_PACKAGE.keys()))), {}

    # 检查agent状态
    err_ips = check_agent_status(nodes)
    if err_ips:
        return -1, "节点检查失败,{}".format(",".join(err_ips)), {}

    # 生成service存放目录
    static_dir = gen_static_dir()
    lu_logger.debug("conf dir:{}".format(static_dir))

    nginx_service_path = NGINX.gen_nginx_service(static_dir, application_dir)
    nginx_conf_path = NGINX.gen_nginx_conf(static_dir)
    empty_conf_path = NGINX.gen_empty_conf(static_dir)

    job = register_job(
        "部署nginx",
        [
            [
                AsyncTaskDeployNginx(
                    "部署nginx",
                    {
                        "nodes": nodes,
                        "pkg": pkg,
                        "application_dir": application_dir,
                        "nginx_service_path": nginx_service_path,
                        "nginx_conf_path": nginx_conf_path,
                        "empty_conf_path": empty_conf_path,
                    }
                )
            ],
        ]
    )
    data = {
        "job_id": job.id,
        "nginx_service_path": get_static_url(nginx_service_path),
        "nginx_conf_path": get_static_url(nginx_conf_path),
        "empty_conf_path": get_static_url(empty_conf_path),
    }

    return 0, "", data


def job_deploy_k8s_lb_with_nginx(params):
    nginx_config_dir = params["nginx_config_dir"]
    nodes = params["nodes"]
    nodes = list(set(nodes))
    lb_port = params["lb_port"]
    server_list = params["server_list"]
    conf_name = params["conf_name"]
    upstream_name = params["upstream_name"]

    # 检查agent状态
    err_ips = check_agent_status(nodes)
    if err_ips:
        return -1, "节点检查失败,{}".format(",".join(err_ips)), {}

    # 生成service存放目录
    static_dir = gen_static_dir()
    lu_logger.debug("conf dir:{}".format(static_dir))

    nginx_conf_path = NGINX.gen_nginx_stream_config(static_dir, upstream_name, server_list, lb_port, conf_name)

    job = register_job(
        "部署nginx-k8s负载均衡",
        [
            [
                AsyncTaskDeployK8SLBWithNginx(
                    "部署nginx-k8s负载均衡",
                    {
                        "nodes": nodes,
                        "nginx_config_dir": nginx_config_dir,
                        "nginx_conf_path": nginx_conf_path,
                        "conf_name": conf_name,
                    }
                ),
            ],
        ]
    )
    data = {
        "job_id": job.id,
        "nginx_conf_path": get_static_url(nginx_conf_path),
    }

    return 0, "", data
